﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SolutionExtender.Controls;
using SolutionExtender.Interfaces;

namespace McTools.SolutionExtender.BusinessUnitPlugin
{
    public class BusinessUnitConnector : IConnector
    {
        #region Variables

        /// <summary>
        /// IOrganization service to access CRM 2011 data
        /// </summary>
        private readonly IOrganizationService _service;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class BusinessUnitConnector
        /// </summary>
        /// <param name="service">IOrganization service to access CRM 2011 data</param>
        public BusinessUnitConnector(IOrganizationService service)
        {
            _service = service;
        }

        #endregion Constructor

        #region Properties

        public string ObjectName
        {
            get { return "Business unit"; }
        }

        public string Description
        {
            get { return "Allows to export Business units"; }
        }

        #endregion Properties

        public List<ImportResult> Import(XmlNode data)
        {
            var importResults = new List<ImportResult>();

            foreach (XmlNode buNode in data.ChildNodes)
            {
                Entity record;

                var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(buNode.OuterXml));

                using (var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8,
                                                                         new XmlDictionaryReaderQuotas(), null))
                {

                    var serializer = new DataContractSerializer(typeof (Entity),
                                                                null,
                                                                int.MaxValue,
                                                                false,
                                                                false,
                                                                null,
                                                                new KnownTypesResolver());

                    record = (Entity) serializer.ReadObject(reader);
                }


                if (record.Contains("parentbusinessunitid"))
                {
                    var reference = (EntityReference) record["parentbusinessunitid"];

                    if (reference.Id == Guid.Empty)
                    {
                        var qe = new QueryExpression("businessunit");
                        qe.Criteria.AddCondition("parentbusinessunitid", ConditionOperator.Null);
                        qe.Criteria.AddCondition("isdisabled", ConditionOperator.Equal, false);
                        qe.ColumnSet = new ColumnSet(true);

                        var results = _service.RetrieveMultiple(qe);

                        record["parentbusinessunitid"] = results.Entities[0].ToEntityReference();
                    }
                }

                try
                {
                    _service.Create(record);
                    importResults.Add(new ImportResult
                        {
                            Message = string.Empty,
                            Succeed = true,
                            Type = ObjectName,
                            Name = GetRecordName(buNode)
                        });
                }
                catch (Exception error)
                {
                    importResults.Add(new ImportResult
                    {
                        Message = error.Message,
                        Succeed = false,
                        Type = ObjectName,
                        Name = GetRecordName(buNode)
                    });
                }
               
            }

            return importResults;
        }

        public IExportControl GetExportControl(IOrganizationService service)
        {
            return new BusinessUnitControl(_service);
        }

        public string GetRecordName(XmlNode node)
        {
            return node.Attributes["name"].Value;
        }
    }
}
